#include "standalonewidget.h"
#include "ui_standalonewidget.h"
#include "userwidget.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QRandomGenerator>
#include <QThread>
#include <QTimer>
#include <QTime>
#include <QMessageBox>
#include <QQueue>
#include <QPair>

const int StandaloneWidget::s_questionNumber = 10;

StandaloneWidget::StandaloneWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StandaloneWidget),
    m_networkAccessManager(Q_NULLPTR),
    m_currentQuestionId(0),
    m_score(0),
    m_timer(Q_NULLPTR)
{
    ui->setupUi(this);

    ui->m_userIdLabel->setText(Global::userId);

    connect(this, &StandaloneWidget::questionsLoaded, this, &StandaloneWidget::startAnswerGame);

    // 获取问题数量
    if (!m_networkAccessManager)
        m_networkAccessManager = new QNetworkAccessManager(this);
    connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, [&](QNetworkReply *reply) {
        m_networkAccessManager->disconnect();
        int questionCount = reply->readAll().toInt();

        // 随机生成问题id
        QVector<int> questionId = getRandomNumbers(1, questionCount, s_questionNumber);

        qDebug() << questionId;

        // 获取问题json数据
        for (int id : questionId)
        {
            m_networkAccessManager = new QNetworkAccessManager(this);
            connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, [&](QNetworkReply *reply) {
                m_networkAccessManager->disconnect();
                m_questions.append(QJsonDocument::fromJson(reply->readAll()).object());
                qDebug() << m_questions.size();
                if (m_questions.size() == 5)
                {
                    qDebug() << "start!!";

                    // 开始游戏
                    emit questionsLoaded();
                }
            });
            QNetworkRequest request;
            request.setUrl(QUrl(Global::serverIp + QString("/question/get_question?question_id=%1").arg(id)));
            m_networkAccessManager->get(request);
        }
    });
    QNetworkRequest request;
    request.setUrl(QUrl(Global::serverIp + QString("/question/get_question_count")));
    m_networkAccessManager->get(request);


}

StandaloneWidget::~StandaloneWidget()
{
    delete ui;
}

void StandaloneWidget::closeEvent(QCloseEvent *event)
{
    m_timer->stop();
    delete m_timer;
    Global::userWidget->show();
}

QVector<int> StandaloneWidget::getRandomNumbers(int start, int end, int count)
{
    if (count <= 0 || start >= end)
        return QVector<int>();

    QVector<int> res;

    // 采用分治算法，二分生成随机数，可以确保生成的随机数没有重复
    QQueue<QPair<int, int>> que;
    int middle = QRandomGenerator::global()->bounded(start, end + 1);
    res.push_back(middle);
    if (middle > start)
        que.push_back(qMakePair(start, middle - 1));
    if (middle < end)
        que.push_back(qMakePair(middle + 1, end));
    while (!que.empty() && res.size() < count)
    {
        int middle = QRandomGenerator::global()->bounded(que.head().first, que.head().second + 1);
        res.push_back(middle);
        if (middle > que.head().first)
            que.push_back(qMakePair(que.head().first, middle - 1));
        if (middle < que.head().second)
            que.push_back(qMakePair(middle + 1, que.head().second));
        que.pop_front();
    }


    return res;
}

void StandaloneWidget::updateScore()
{
    if (!m_networkAccessManager)
        m_networkAccessManager = new QNetworkAccessManager(this);
    connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, [&](QNetworkReply *reply) {
        m_networkAccessManager->disconnect();
        if (reply->readAll() == "true")
        {
            QMessageBox messageBox(this);
            messageBox.setText(u8"游戏结束，得分为" + QString::number(m_score));
            messageBox.setWindowTitle(u8"得分结果");
            messageBox.exec();
            this->close();
        }
        else
        {
            QMessageBox messageBox(this);
            messageBox.setText(u8"更新用户得分失败！");
            messageBox.exec();
            this->close();
        }
    });
    QNetworkRequest request;
    request.setUrl(QUrl(Global::serverIp + QString("/user/add_score?user_id=%1&score=%2").arg(Global::userId).arg(m_score)));
    m_networkAccessManager->get(request);
}

void StandaloneWidget::showQuestion()
{
    QJsonObject questionJson = m_questions[m_currentQuestionId].toObject();

    // 回答正确函数
    auto answerCorrect = [&]() {
        m_timer->stop();
        qDebug() << "answer correct!";
        m_score += 15 - m_time.second();
        ui->m_scoreProgressBar->setValue(m_score);
        ui->m_scoreLabel->setText(u8"分数：" + QString::number(m_score));
        m_currentQuestionId++;
        if (m_currentQuestionId >= m_questions.size())
        {
            updateScore();
            return;
        }
        m_time.setHMS(0, 0, 0);
        showQuestion();
        m_timer->start(1000);
    };

    // 回答错误函数
    auto answerWrong = [&]() {
        m_timer->stop();
        qDebug() << "answer wrong!";
        m_currentQuestionId++;
        if (m_currentQuestionId >= m_questions.size())
        {
            updateScore();
            return;
        }
        m_time.setHMS(0, 0, 0);
        showQuestion();
        m_timer->start(1000);
    };

    // 显示问题
    ui->m_questionTextBrowser->setPlainText(questionJson.value("question").toString());

    // 显示答案选项
    // index是选项编号(1代表A, 2代表B, 以此类推)
    QVector<int> indexs = getRandomNumbers(1, 4, 4);
    ui->m_AButton->disconnect();
    ui->m_BButton->disconnect();
    ui->m_CButton->disconnect();
    ui->m_DButton->disconnect();
    switch(indexs[0])
    {
        case 1:
            ui->m_AButton->setText("A " + questionJson.value("correctAnswer").toString());
            connect(ui->m_AButton, &QPushButton::clicked, this, answerCorrect);
            break;
        case 2:
            ui->m_AButton->setText("A " + questionJson.value("wrongAnswer0").toString());
            connect(ui->m_AButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 3:
            ui->m_AButton->setText("A " + questionJson.value("wrongAnswer1").toString());
            connect(ui->m_AButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 4:
            ui->m_AButton->setText("A " + questionJson.value("wrongAnswer2").toString());
            connect(ui->m_AButton, &QPushButton::clicked, this, answerWrong);
            break;
    }
    switch(indexs[1])
    {
        case 1:
            ui->m_BButton->setText("B " + questionJson.value("correctAnswer").toString());
            connect(ui->m_BButton, &QPushButton::clicked, this, answerCorrect);
            break;
        case 2:
            ui->m_BButton->setText("B " + questionJson.value("wrongAnswer0").toString());
            connect(ui->m_BButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 3:
            ui->m_BButton->setText("B " + questionJson.value("wrongAnswer1").toString());
            connect(ui->m_BButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 4:
            ui->m_BButton->setText("B " + questionJson.value("wrongAnswer2").toString());
            connect(ui->m_BButton, &QPushButton::clicked, this, answerWrong);
            break;
    }
    switch(indexs[2])
    {
        case 1:
            ui->m_CButton->setText("C " + questionJson.value("correctAnswer").toString());
            connect(ui->m_CButton, &QPushButton::clicked, this, answerCorrect);
            break;
        case 2:
            ui->m_CButton->setText("C " + questionJson.value("wrongAnswer0").toString());
            connect(ui->m_CButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 3:
            ui->m_CButton->setText("C " + questionJson.value("wrongAnswer1").toString());
            connect(ui->m_CButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 4:
            ui->m_CButton->setText("C " + questionJson.value("wrongAnswer2").toString());
            connect(ui->m_CButton, &QPushButton::clicked, this, answerWrong);
            break;
    }
    switch(indexs[3])
    {
        case 1:
            ui->m_DButton->setText("D " + questionJson.value("correctAnswer").toString());
            connect(ui->m_DButton, &QPushButton::clicked, this, answerCorrect);
            break;
        case 2:
            ui->m_DButton->setText("D " + questionJson.value("wrongAnswer0").toString());
            connect(ui->m_DButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 3:
            ui->m_DButton->setText("D " + questionJson.value("wrongAnswer1").toString());
            connect(ui->m_DButton, &QPushButton::clicked, this, answerWrong);
            break;
        case 4:
            ui->m_DButton->setText("D " + questionJson.value("wrongAnswer2").toString());
            connect(ui->m_DButton, &QPushButton::clicked, this, answerWrong);
            break;
    }
}

void StandaloneWidget::startAnswerGame()
{
    showQuestion();

    m_time.setHMS(0, 0, 0);

    m_timer = new QTimer(this);
    m_timer->start(1000);
    connect(m_timer, &QTimer::timeout, this, [&]() {
        m_time = m_time.addSecs(1);
        ui->m_timeProgressBar->setValue(15 - m_time.second());
        if (m_time.second() >= 15)
        {
            m_timer->stop();
            m_currentQuestionId++;
            if (m_currentQuestionId >= m_questions.size())
            {
                updateScore();
                return;
            }
            m_time.setHMS(0, 0, 0);
            showQuestion();
            m_timer->start(1000);
        }
    });
}
